#region Using directives

using System;
using System.Diagnostics;
using System.Collections.Generic;

using Weazel.Math;

#endregion

namespace Weazel.Gezel.Simulator.Reference
{
  class ProxySignal : AbstractSignal
  {
    private readonly AbstractSignal baseSignal; 
    private Integer value; 
    private readonly int startIndex;
    private readonly int endIndex;
    private readonly int length;

    public ProxySignal(Symid id, AbstractSignal baseSignal, int firstIndex, int secondIndex) : base(id, null)
    {
      this.baseSignal = baseSignal;
      this.startIndex = System.Math.Min(firstIndex, secondIndex);
      this.endIndex = System.Math.Max(firstIndex, secondIndex);
      this.length = endIndex - startIndex + 1;

      Trace.Assert(length > 0, "error, signal bitwidth must be greater than zero");
      this.value = new Integer(length, false);
    }

    internal override void newDefiner(Symid _sfg, AbstractSignal _definer)
    {
      throw new NotSupportedException("assigning to proxies is not supported");
    }

    internal override void defineDriver(AbstractSignal d)
    {
      throw new NotSupportedException("assigning to proxies is not supported");
    }

    internal override Integer Evaluate(AbstractIpBlock ip, long g)
    {
      Integer i = baseSignal.Evaluate(ip, g);
      Integer.GetRange(ref value, i, startIndex, endIndex);
      return value;
    }

    internal override Integer PeekValue()
    {
      return value;
    }

    internal override uint Width()
    {
      return (uint)length;
    }

    internal override uint Signed()
    {
      return 0; // unsigned
    }

    public override bool TraceToSignal(Symid toSignalId, List<AbstractSignal> signals)
    {
      return baseSignal.TraceToSignal(toSignalId, signals);
    }
  }
}
